//
// Created by wangrl on 19-4-12.
//

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>

struct Base {
    Base() { std::cout << " Base::Base()\n"; }
    // Note: non-virtual destructor is OK here
    ~Base() { std::cout << " Base::~Base()\n"; };
};

struct Derived : public Base {
    Derived() { std::cout << " Derived::Derived()\n"; }
    ~Derived() { std::cout << " Derived::~Derived() \n"; }
};

void thr(std::shared_ptr<Base> p) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::shared_ptr<Base> lp = p;   // thread-safe, even though the
                                    // shared use_count is incremented
    {
        static std::mutex io_mutex;
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << "local pointer in a thread:\n"
                << " lp.get() = " << lp.get()
                << ", lp.use_count() = " << lp.use_count() << '\n';
    }
}

int main(int argc, char *argv[]) {
    // 先构造Base，再构造Derived，
    // 先释放Derived，再释放Base.
    std::shared_ptr<Base> p = std::make_shared<Derived>();

    std::cout << "Created a shared Derived (as a pointer to Base)\n"
            << " p.get() = " << p.get()
            << ", p.use_count() = " << p.use_count() << '\n';

    std::thread t1(thr, p), t2(thr, p), t3(thr, p);

    p.reset();      // release ownership from main
    std::cout << "Shared ownership between 3 threads and released\n"
            << "ownership from main:\n"
            << " g.get() = " << p.get()
            << ", p.use_count() = " << p.use_count() << '\n';
    t1.join();
    t2.join();
    t3.join();
    std::cout << "All threads completed, the last one deleted Derived\n";
}